[C#] PdfTemplate.iTextSharp.LGPLv2 產生Pdf 範例


Posted by mike-hsieh on 2023-09-15

簡單紀錄一個使用 PdfTemplate.iTextSharp.LGPLv2 產生Pdf的程式碼,包含以下重點:

  1. 尺寸為A4,字體為標楷體。
  2. 每頁都要有Header、Footer,Header = "測試文檔",Footer = 當前日期時間。
  3. 資料來源是[Northwind北風資料庫]的[Orders]。
  4. 每頁都要有浮水印、傾斜45度、可調整透明度、文字為"公司機密"。
  5. 用byte方式輸出。
public byte[] GeneratePdf()
{
    // 創建一個MemoryStream,用於保存 PDF 文件的內容
    MemoryStream stream = new MemoryStream();

    try
    {
        // 創建一個新的A4文檔
        Document doc = new Document(PageSize.A4);

        // 使用 PdfWriter 將文檔寫入到 MemoryStream 中
        PdfWriter writer = PdfWriter.GetInstance(doc, stream);

        // 自定義 Header 和 Footer
        writer.PageEvent = new PdfHeaderFooter();

        doc.Open();

        // 從數據庫獲取訂單數據
        DataTable ordersData = GetOrdersDataFromDatabase();

        // 創建一個 PdfPTable 來顯示訂單數據
        PdfPTable table = new PdfPTable(4); // 假設有4列數據

        // 添加表頭
        table.AddCell(new PdfPCell(new Phrase("Order ID")));
        table.AddCell(new PdfPCell(new Phrase("Customer ID")));
        table.AddCell(new PdfPCell(new Phrase("Order Date")));
        table.AddCell(new PdfPCell(new Phrase("Ship Name")));

        // 添加訂單數據行
        foreach (DataRow row in ordersData.Rows)
        {
            table.AddCell(row["OrderID"].ToString());
            table.AddCell(row["CustomerID"].ToString());
            table.AddCell(((DateTime)row["OrderDate"]).ToString("yyyy-MM-dd"));
            table.AddCell(row["ShipName"].ToString());
        }

        doc.Add(table);

        doc.Close();

        byte[] pdfBytes = stream.ToArray();

        return pdfBytes;
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        stream.Dispose();
    }
}

// 自定義Header和Footer
private class PdfHeaderFooter : PdfPageEventHelper
{
    public override void OnEndPage(PdfWriter writer, Document document)
    {
        ///  使用BaseFont類創建字體。 (使用windows內建的標楷體)
        BaseFont baseFont = BaseFont.CreateFont("c:\\windows\\fonts\\KAIU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

        /// 添加Header
        #region 添加Header
        PdfPTable headerTable = new PdfPTable(1);
        PdfPCell headerCell = new PdfPCell(new Paragraph("測試文檔", new Font(baseFont, 12, Font.BOLD)));
        headerCell.HorizontalAlignment = Element.ALIGN_CENTER;
        headerTable.AddCell(headerCell);
        headerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
        headerTable.WriteSelectedRows(0, -1, document.LeftMargin, document.PageSize.Height - document.TopMargin + headerTable.TotalHeight, writer.DirectContent);
        #endregion

        #region 繪製浮水印
        // 創建一個 PdfContentByte 用於繪製浮水印
        PdfContentByte cb = writer.DirectContentUnder;

        // 設置字體和大小
        Font font = new Font(baseFont, 12);
        cb.SetFontAndSize(baseFont, 12);

        // 設置浮水印文本
        string watermarkText = $@"公司機密";

        // 獲取頁面尺寸
        Rectangle pageSize = document.PageSize;

        // 設置浮水印的顏色和透明度
        cb.SetColorFill(BaseColor.LightGray);
        cb.SetGState(new PdfGState { FillOpacity = 0.25f }); // 設置透明度

        // 計算行間距和列間距
        float lineHeight = font.GetCalculatedLeading(15);
        float columnWidth = 100; // 每列的寬度
        float marginX = 20; // 水平邊距
        float marginY = 20; // 垂直邊距

        // 計算每頁可容納的行數和列數
        int rowsPerPage = (int)((pageSize.Height - 2 * marginY) / lineHeight);
        int columnsPerPage = (int)((pageSize.Width - 2 * marginX) / columnWidth);

        // 循環繪製浮水印
        for (int row = 0; row < rowsPerPage; row++)
        {
            for (int column = 0; column < columnsPerPage; column++)
            {
                float x = marginX + column * columnWidth;
                float y = pageSize.Height - marginY - row * lineHeight;

                // 繪製浮水印文本
                cb.BeginText();
                cb.ShowTextAligned(Element.ALIGN_LEFT, watermarkText, x, y, 45); // 45度傾斜
                cb.EndText();
            }
        }
        #endregion

        /// 添加Footer
        #region 添加Footer                
        PdfPTable footerTable = new PdfPTable(1);
        PdfPCell footerCell = new PdfPCell(new Paragraph(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new Font(baseFont, 12, Font.BOLD))); 
        footerCell.HorizontalAlignment = Element.ALIGN_CENTER;
        footerTable.AddCell(footerCell);
        footerTable.TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin;
        footerTable.WriteSelectedRows(0, -1, document.LeftMargin, document.BottomMargin - footerTable.TotalHeight, writer.DirectContent);
        #endregion
    }
}

private DataTable GetOrdersDataFromDatabase()
{
    // 連接到數據庫,查詢Orders表,返回數據
    string connectionString = "Data Source=.;Initial Catalog=NorthWind;Integrated Security=SSPI;";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        string query = "SELECT * FROM Orders";
        SqlCommand command = new SqlCommand(query, connection);
        SqlDataAdapter adapter = new SqlDataAdapter(command);
        DataTable dataTable = new DataTable();
        adapter.Fill(dataTable);
        return dataTable;
    }
}

以下為輸出的範例:


#PdfTemplate.iTextSharp.LGPLv2 #Header、Footer #byte #A4 #watermark







Related Posts

Day07 從 React-router 看 History API

Day07 從 React-router 看 History API

v-model 與.修飾符

v-model 與.修飾符

Day 5 - For Loop

Day 5 - For Loop


Comments